package hu.monitor.remoting.transport.socket;

import hu.monitor.remoting.transport.ServerEndpointAdapter;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SocketServerEndpoint extends Thread {
	private static Logger log = LoggerFactory.getLogger(SocketServerEndpoint.class);

	private final ExecutorService threadPool = Executors.newCachedThreadPool();
	private ServerSocket serverSocket;
	private final SocketAddress socketAddress;
	private final ServerEndpointAdapter adapter;

	public SocketServerEndpoint(final SocketAddress socketAddress, final ServerEndpointAdapter adapter) {
		this.socketAddress = socketAddress;
		this.adapter = adapter;
	}

	public void startAcceptor() throws IOException {
		this.serverSocket = new ServerSocket();
		log.info("binding to {}", this.socketAddress);
		this.serverSocket.bind(this.socketAddress);
		this.start();
	}

	public void stopAcceptor() throws IOException {
		log.info("stop listening on {}", this.socketAddress);
		this.interrupt();
		this.serverSocket.close();
	}

	@Override
	public void run() {
		while (!interrupted()) {
			try {
				log.debug("waiting for connection: {}", this.serverSocket);
				final Socket socket = this.serverSocket.accept();
				log.debug("connect accepted: {}", socket);
				this.threadPool.submit(new Worker(socket, this.adapter));
			} catch (final IOException ex) {
				log.error(ex.getMessage(), ex);
			}
		}
	}
}
